package com.vista.beans;

import java.io.IOException;
import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import javax.faces.event.MethodExpressionActionListener;

import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.model.DefaultMenuModel;
import org.primefaces.model.MenuModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.comun.utils.Constantes;
import com.facade.proveedor.IGestionProveedor;
import com.facade.rolsubtarea.IGestionRolSubtarea;
import com.facade.tarea.IGestionTarea;
import com.modelo.entity.Proveedor;
import com.modelo.entity.Rolsubtarea;
import com.modelo.entity.Tarea;

@Component
@Scope("session")
public class MenuBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Autowired
	private IGestionTarea igt;
	@Autowired
	private IGestionRolSubtarea igrs;
	@Autowired
	private IGestionProveedor igp;

	private MenuModel menuModel;

	public MenuBean() {
	}

	@PostConstruct
	public void crearMenu() {
		// para cuando se loguee se recoge el proveedor de la sesion
		// Proveedor p = (Proveedor) Accesos_Contextos.getSesion().getAttribute(
		// "Proveedor");

		Proveedor p = igp.findById(1);
		List<Rolsubtarea> rsList = igrs.getSubtareasFromRol(p.getRol());

		menuModel = new DefaultMenuModel();

		// create submenu
		Submenu submenu = new Submenu();
		MenuItem menuSubtarea;
		Tarea tAnt;

		// Inicializamos la primera tarea
		tAnt = rsList.get(0).getSubtarea().getTarea();
		submenu.setId("submenu_" + tAnt.getIdtarea().toString());
		submenu.setLabel(tAnt.getNombre());
		submenu.setStyleClass(Constantes.CSS_CLASE_BASE_MENU
				+ " "
				+ Constantes.CSS_CLASE_BASE_MENU_IMAGEN.concat(tAnt.getNombre()));

		/*
		 * Lo que hace es recorrer rolSubtarea, de tal forma que guarda una
		 * tarea, y va recorriendo todas las subtareas, y cuando ve que cambia
		 * la tarea entonces creamos otro menuItem.
		 */
		for (Rolsubtarea rs : rsList) {
			if (rs.getSubtarea().getTarea().getIdtarea() == tAnt.getIdtarea()) {
				menuSubtarea = new MenuItem();

			} else {
				// Introducimos el menuTarea que hemos configurado.
				menuModel.addSubmenu(submenu);

				// Guardamos la tarea que hay nueva.
				tAnt = rs.getSubtarea().getTarea();
				submenu = new Submenu();
				submenu.setId("submenu_" + tAnt.getIdtarea().toString());
				submenu.setLabel(tAnt.getNombre());
				submenu.setStyleClass(Constantes.CSS_CLASE_BASE_MENU
						+ " "
						+ Constantes.CSS_CLASE_BASE_MENU_IMAGEN.concat(tAnt
								.getNombre()));

				menuSubtarea = new MenuItem();
			}

			// Le damos el nombre a la tarea
			menuSubtarea.setValue(rs.getSubtarea().getNombre());
			menuSubtarea.setId(rs.getSubtarea().getEnlace());
			try {

				menuSubtarea
						.setActionExpression(getMethodExpressionAction("#{menuBean."
								+ rs.getSubtarea().getEnlace() + "}"));
			} catch (Exception e) {
				e.printStackTrace();
			}

			menuSubtarea.setAjax(false);
			menuSubtarea
					.setStyleClass(Constantes.CSS_CLASE_BASE_SUBMENU
							+ " "
							+ Constantes.CSS_CLASE_BASE_SUBMENU_IMAGEN
									.concat(rs.getSubtarea().getNombre()
											.concat(tAnt.getNombre())));

			// Agregamos la subtareaMenu a la tareaMenu
			submenu.getChildren().add(menuSubtarea);
		}
		// Para que agregue el ultimo menuTarea que configuramos.
		menuModel.addSubmenu(submenu);
	}

	// Documento
	public String docNuevo() {
		return "docNuevo";
	}

	public String docEliminar() {
		return "docEliminar";
	}

	public String docModificar() {
		return "docModificar";
	}

	// Obra
	public String obraNueva() {
		return "obraNueva";
	}

	public String obraEliminar() {
		return "obraEliminar";
	}

	public String obraModificar() {
		return "obraModificar";
	}

	// Proveedor
	public String proveedorNuevo() {
		return "proveedorNuevo";
	}

	public String proveedorEliminar() {
		return "proveedorEliminar";
	}

	public String proveedorModificar() {
		return "proveedorModificar";
	}

	@SuppressWarnings("rawtypes")
	public MethodExpression actionMethoExpression(String actionName,
			boolean listener) {
		MethodExpression methodExpression = null;

		Class[] argumentTypes = new Class[0];

		if (listener) {
			argumentTypes[0] = ActionEvent.class;
		}
		ELContext elContext = getELContext();
		methodExpression = createMethodExpression(elContext, actionName, null,
				argumentTypes);
		try {
			methodExpression.getMethodInfo(elContext);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return methodExpression;
	}

	private FacesContext getFacesContext() {
		return FacesContext.getCurrentInstance();
	}

	private Application getApplication() {
		return getFacesContext().getApplication();
	}

	private ExpressionFactory getExpressionFactory() {
		return getApplication().getExpressionFactory();
	}

	private ELContext getELContext() {
		return getFacesContext().getELContext();
	}

	@SuppressWarnings("rawtypes")
	private MethodExpression createMethodExpression(ELContext elContext,
			String actionName, Class clazz, Class[] argumentTypes) {
		return getExpressionFactory().createMethodExpression(elContext,
				actionName, clazz, argumentTypes);
	}

	public IGestionTarea getIgt() {
		return igt;
	}

	public void setIgt(IGestionTarea igt) {
		this.igt = igt;
	}

	public void setIgrs(IGestionRolSubtarea igrs) {
		this.igrs = igrs;
	}

	public void setIgp(IGestionProveedor igp) {
		this.igp = igp;
	}

	public MenuModel getMenuModel() {
		return menuModel;
	}

	public void setMenuModel(MenuModel menuModel) {
		this.menuModel = menuModel;
	}

	// ESTA VALE para los Action listener con paramtros actionevent de esta
	// forma encuentra el action, pero
	// no redirige
	private MethodExpression getMethodExpressionAction(String name) {
		Class[] argtypes = new Class[0];
		FacesContext facesCtx = FacesContext.getCurrentInstance();
		Application app = facesCtx.getApplication();
		ExpressionFactory elFactory = app.getExpressionFactory();
		ELContext elContext = facesCtx.getELContext();
		return elFactory
				.createMethodExpression(elContext, name, null, argtypes);
	}

	// ESTA VALE para los Action listener con paramtros actionevent
	private MethodExpression getMethodExpressionActionListener(String name) {
		Class[] argtypes = new Class[1];
		argtypes[0] = ActionEvent.class;
		FacesContext facesCtx = FacesContext.getCurrentInstance();
		Application app = facesCtx.getApplication();
		ExpressionFactory elFactory = app.getExpressionFactory();
		ELContext elContext = facesCtx.getELContext();
		return elFactory
				.createMethodExpression(elContext, name, null, argtypes);
	}

}
